﻿using System;
using System.Management;
using System.IO;
using System.Runtime.InteropServices;
using System.Security.Cryptography;
using System.Text;
using Microsoft.Win32;
using System.Web;
using System.Net;

namespace VeryCodes.Common
{
    ///  <summary> 
    /// register 的摘要说明。 
    /// 注册软件所用到的类 
    ///  </summary> 
    public class HardWareInfo
    {
        /// <summary>
        /// 获取cpu序列号
        /// </summary>
        /// <returns>string</returns>
        public string GetCpuInfo()
        {
            string cpuInfo = "";
            try
            {
                ManagementClass cimobject = new ManagementClass("Win32_Processor");
                ManagementObjectCollection moc = cimobject.GetInstances();
                foreach (ManagementObject mo in moc)
                {
                    cpuInfo = mo.Properties["ProcessorId"].Value.ToString();
                }
            }
            catch (Exception ex)
            {
                LogHelper.ToWarn("获取服务器CPU ID失败", ex);
            }

            return cpuInfo.ToString();
        }

        ///  <summary> 
        /// 获取硬盘ID   
        ///  </summary> 
        ///  <returns>string </returns> 
        public string GetHDid()
        {
            string HDid = "";
            try
            {
                ManagementClass cimobject1 = new ManagementClass("Win32_DiskDrive");
                ManagementObjectCollection moc1 = cimobject1.GetInstances();
                foreach (ManagementObject mo in moc1)
                {
                    HDid = (string)mo.Properties["Model"].Value;
                }
            }
            catch (Exception ex)
            {
                LogHelper.ToWarn("获取服务器硬盘 ID失败", ex);
            }

            return HDid.ToString();
        }

        ///  <summary> 
        /// 获取网卡硬件地址 
        ///  </summary> 
        ///  <returns>string </returns> 
        public string GetMoAddress()
        {
            string MoAddress = "";
            try
            {
                ManagementClass mc = new ManagementClass("Win32_NetworkAdapterConfiguration");
                ManagementObjectCollection moc2 = mc.GetInstances();
                foreach (ManagementObject mo in moc2)
                {
                    if ((bool)mo["IPEnabled"] == true)
                        MoAddress = mo["MacAddress"].ToString();
                    mo.Dispose();
                }
            }
            catch (Exception ex)
            {
                LogHelper.ToWarn("获取服务器网卡硬件地址失败", ex);
            }

            return MoAddress.ToString();
        }

        /// <summary>
        /// 获取机器码
        /// </summary>
        /// <returns></returns>
        public string GetComputerCode()
        {
            string cpuid = GetCpuInfo();
            string hdid = GetHDid();
            string moaddress = GetMoAddress();
            string filepath = HttpContext.Current.Request.PhysicalApplicationPath;

            string newcomputerCode = "";
            string computerCode = FormatComputerCode(cpuid, hdid, moaddress, filepath);
            int bcount = 0;//新的机器码中4个字符为一段
            int bbcount = 0;//新的机器码最多只有5段

            if (computerCode.Length > 20)
            {
                int blength = computerCode.Length / 5;//分成五段，每段的字符数

                for (int i = 0; i < computerCode.Length; i++)
                {
                    newcomputerCode += computerCode[i].ToString();
                    bcount++;

                    if (bcount >= 4)
                    {
                        i = i + (blength - bcount);//跳过原密码的这一段 进入下一段取字符
                        bbcount++;

                        if (bbcount >= 5)
                        {
                            break;
                        }
                        newcomputerCode += "-";
                        bcount = 0;
                    }
                }
            }
            else
            {
                foreach (byte tmpbyte in computerCode)
                {
                    newcomputerCode += tmpbyte.ToString();
                    bcount++;

                    if (bcount >= 4)
                    {
                        bbcount++;
                        if (bbcount >= 5)
                        {
                            break;
                        }
                        newcomputerCode += "-";
                        bcount = 0;
                    }
                }
            }

            return newcomputerCode;
        }

        /// <summary>
        /// 格式化机器码信息
        /// </summary>
        /// <param name="cpuid">The cpuid.</param>
        /// <param name="hdid">The hdid.</param>
        /// <param name="moaddress">The moaddress.</param>
        /// <param name="filepath">The filepath.</param>
        /// <returns></returns>
        private string FormatComputerCode(string cpuid, string hdid, string moaddress, string filepath)
        {
            string computerCode = hdid.ToUpper() + filepath.ToUpper() + cpuid.ToUpper() + moaddress.ToUpper() + GetIP().ToUpper();

            if (computerCode != "")
            {
                computerCode = FormatComputerCode(computerCode);
            }
            return computerCode;
        }

        /// <summary>
        /// 格式化机器码
        /// </summary>
        /// <param name="computerCode"></param>
        /// <returns></returns>
        private string FormatComputerCode(string computerCode)
        {
            computerCode = computerCode.Replace(":", "");
            computerCode = computerCode.Replace(" ", "B");
            computerCode = computerCode.Replace("_", "U");
            computerCode = computerCode.Replace("\\", "I");
            computerCode = computerCode.Replace(".", "D");
            computerCode = computerCode.Replace("-", "L");
            computerCode = Reverse(computerCode);
            return computerCode;
        }

        /// <summary>
        /// 转换为ASCII
        /// </summary>
        /// <returns></returns>
        private string ToUTF8(string str)
        {
            string code = "";
            System.Text.Encoding encoding = System.Text.Encoding.UTF8;
            byte[] ByteArray1 = encoding.GetBytes(str);
            for (int i = 0; i < ByteArray1.Length; i++)
            {
                code += ByteArray1[i].ToString();
            }

            if (code.Length >= 9)
            {
                code = code.Substring(4, 3);
            }

            return code;
        }


        /// <summary>
        /// 反转字符串
        /// </summary>
        /// <param name="text"></param>
        /// <returns></returns>
        private string Reverse(string text)
        {
            char[] cArray = text.ToCharArray();
            StringBuilder reverse = new StringBuilder();
            for (int i = cArray.Length - 1; i > -1; i--)
            {
                if (IsChina(cArray[i].ToString()))
                {
                    reverse.Append(ToUTF8(cArray[i].ToString()));
                }
                else
                {
                    reverse.Append(cArray[i]);
                }
            }
            return reverse.ToString();
        }

        /// <summary>
        /// 获取服务器IP
        /// </summary>
        /// <returns></returns>
        public string GetIP()
        {
            string strHostName = Dns.GetHostName(); //得到本机的主机名
            IPHostEntry ipEntry = Dns.GetHostEntry(strHostName); //取得本机IP
            string strAddr = ipEntry.AddressList[0].ToString();
            return strAddr;
        }

        /// <summary>
        /// 判断是否中文
        /// </summary>
        /// <param name="CString">The C string.</param>
        /// <returns>
        /// 	<c>true</c> if the specified C string is china; otherwise, <c>false</c>.
        /// </returns>
        public bool IsChina(string CString)
        {
            bool BoolValue = false;
            for (int i = 0; i < CString.Length; i++)
            {
                if (Convert.ToInt32(Convert.ToChar(CString.Substring(i, 1))) < Convert.ToInt32(Convert.ToChar(128)))
                {
                    BoolValue = false;
                }
                else
                {
                    return BoolValue = true;
                }
            }
            return BoolValue;
        }
    }
}
